API Design
This section looks at API design and offers the standards required to support health sector organisations in designing, developing and governing APIs. The intended audience for this section of the document is technical for example API developers, or API designers.
When reading this section consider the implications for your organisation. Fundamentally, APIs should make interoperability with your organisation simple, but more importantly consistent.
Application developers will invest heavily in using your API. They will invest in learning the design and behaviour of your API, in developing and testing around your API and may even invest in developing an entire business model on your API.
Good API designs will attract more developers. Conversely, bad API designs will drive away developers and drive up costs – support costs, maintenance costs and operating costs.
When is an API appropriate?
In the past, the default reaction to a requirement for capability has been to develop a web application. This is now gravitating towards APIs as the default. So, when is it better to build an API than a web application? Below are some situations where an API may be more appropriate:
-
When applications are screen scraping data from your website
-
When your organisation holds a single authoritative source of the truth
-
Where there is a need for real or near real time information exchange with a partner
-
When parts of a business process are (or may be) outsourced
-
When your organisation data or service can be included as part of a larger business process
-
When there is a requirement for internal systems to interact with cloud-based COTS solutions (SaaS)
-
Where businesses require easy access to (public) information
-
Where commercial organisations want to build capability into their own applications that will benefit the public (mobile/web apps)
-
If you expect other parties to act as agents or intermediaries for services provided by your organisation
-
When multiple service delivery channels are in use.
Developing traditional applications for each of these situations would be expensive and time consuming. Developing APIs allows you to focus on the access to your data, the quality, integrity and security considerations to protect the value of the data while other organisations develop applications or uses for the data specific to them. This is a change in thinking from functionality and applications to make data available to others for them to use.
Types of API
There are several different types of API and the type you choose may depend on the technical use cases that you apply to both consumption and provision of your API.
| API Type | Description | Usage | Status |
|---|---|---|---|
| REST | Representational State Transfer (REST) is the most common and well understood API type. REST should be considered an architectural style for developing distributed hypermedia systems. There is a wealth of information and tooling to support the definition and creation of REST APIs. Typically, a REST API will have a well-defined and strongly typed schema definition (OpenAPI) where strict compliance can be achieved. | Creating distributed systems where a set of API resources are well defined. If medium latency resource creation or modification (POST, PUT, DELETE) is required then typically a REST API is a better fit. Typically used for synchronous interactions. | MAY support💡 |
| GraphQL | GraphQL is an open source query and manipulation language developed by Facebook primarily designed to empower API consumers to consume only the data that they require. A common criticism of REST is that only the entire resource is available for consumption, sometimes referred to as “over fetching”, however with GraphQL the client decides the data that it requires. GraphQL also has a strongly typed schema (GraphQL Schema Definition Language – SDL). | An API that has a widely distributed client set with a variety of data requirements. Particularly well suited to high read (GET) clients | MAY support💡 |
| Asynchronous APIs | AsyncAPI is an open source initiative to create an event-driven and asynchronous API standardization and development tooling. The AsyncAPI specification, inspired by the OpenAPI specification, describes and documents event-driven APIs in a machine-readable format. | Creating distributed systems where a set of API resources are well defined. Typically used for asynchronous interactions and event driven architectures. Also, useful when developing APIs that front workflows or long running orchestrations. | MAY support💡 |
| gRPC | gRPC is a modern open source high performance Remote Procedure Call (RPC) framework that can run in any environment. | Creating distributed systems that require highly performant and scalable API's. gRPC makes use of binary data rather than just text which makes the communication more compact and more efficient. In gRPC, a client application can directly call a method on a server application on a different machine as if it were a local object, making it easier for you to create distributed applications and services. This is enabled by a formal Interface Definition Language (IDL). gRPC utilizes Protocol Buffers by default, you can make it work with other data formats, such as JSON. | MUST NOT support💡 |
| SOAP | SOAP APIs are formatted as XML files and they are extremely common web communication protocols. The acronym stands for Simple Object Access Protocol, and it was developed in the late 1990s. Despite its age, SOAP still remains one of the more popular API types used by developers. | Stateful operations; if the application needs contextual information and conversational state management then SOAP 1.2 has the additional specification in the WS* structure to support those things (Security, Transactions, Coordination, etc). Comparatively, the REST approach would make the developers build this custom plumbing. | MAY support💡 |
Example Technical Use Case Synchronous/Asynchronous API
The illustrative example below demonstrates a combination of a synchronous API and an asynchronous API.
Detailed description of figure
The diagram illustrates the use case of the Synchronous/Asynchronous Claims API for funded products and services. It depicts the interactions between various entities involved in the API, including API Consumer registration, claim creation, event subscription, and real-time notification updates. The API Consumer initiates the registration process by sending a POST request to the API Provider's /register endpoint. The Health Sector Participant accesses a funded product or service, prompting the Health Sector Organisation to generate claim details and send them to the API Consumer. The API Consumer forwards the claim details to the API Provider, who registers the claim in the API Provider Core System and relays a claim identifier and status back to the API Consumer. The API Consumer subscribes to claim events for a specific claim identifier by sending a SUB request to the API Provider's /claims/{claimId} endpoint. Upon claim status updates, the API Provider Core System generates a notification and transmits it to the API Provider. The API Provider publishes the notification to the API Consumer's registered notification endpoint, who relays it to the Health Sector Participant. The Health Sector Participant then informs the Health Sector Participant of the status update.
The example above has two associated API specifications. The first is an OpenAPI specification that describes the "Create Claim” and "Get Claim” RESTful interactions and the second is an AsyncAPI specification that describes the "Receive Updates” interaction. These example specifications are available for reference here
API Design Principles
Future-Focused Design
APIs SHOULD NOT expose obsolete or legacy structures or functions.💡
Good API design seeks to avoid future breakage in dependent consumer applications by minimising functions, data structures and behaviour exposed, while planning for (at least signalling) foreseeable future change.
Like any interface that has to be maintained, less is definitely more when it comes to functions, structures and behaviour exposed.
Layering
When designing and developing an API it is important to consider that an API is made up of distinct functional layers:
-
Security
-
Caching
-
Representation
Security
Every API will have a security component. It is important to recognise that this is not only authentication and authorisation for access to an API, it also includes threat protection (DDoS, SQL Injection, Cross site scripting etc.) as well as availability and quality of service (QoS). When designing and developing APIs it is often cost effective to create a common framework that handles security for all APIs. See the associated document, Part B: API Security, for more details.
Caching
Caching can dramatically improve the performance of an API. When designing APIs consider what, when and where to cache. Understanding how data is changed and how often it is changed is an important consideration, as well as which layer it is most appropriate to cache at. A common caching strategy should be developed for APIs that would benefit from it. See Caching for more details.
Detailed description of figure
The diagram illustrates the interactions between a health sector participant, an API consumer, security, caching and API components. The health sector participant initiates the process by performing some action within the API consumer. The API consumer makes a request and calls the security component for authentication and authorisation. The security component communicates with the cache which fulfils or passes through the data request as needed. Behind the cache is the API component itself which implements the API's operations and defines the representation of data served. A response flow returns data to the API consumer in the opposite direction.
Standards-Based
Web standards have rapidly become powerful agreements, which span not just local regions but are internationally accepted and enable commonality and consistency. Using standard HTTP and URLs, the core technologies of the web, along with standards such as JSON and OAuth 2.0 ensures that organisations are not creating bespoke or proprietary technologies.
Hence the principle is to build to the latest versions of existing open and accepted standards e.g.
- HTTP
- OpenAPI
- AsyncAPI
- REST
- JSON
- OAuth 2.0
- OIDC
Refer to the API Development Industry Standards for detailed information about relevant standards.
Designing an API
When designing an API, it is important to perform business process analysis to ensure that API development is business-driven rather than technology-driven. Technology driven projects rarely meet customers’ needs in the long run, so it is important to gain background in who could be using the API and for what. As mentioned previously, co-design is fundamental to driving the right API development. To help identify potential partners to involve in the co-design, consider:
-
processes that currently depend on information the API could expose
-
processes that require a capability an API could expose
Some actors in the design process will be human such as application developers or health sector participants whilst some actors will be systems or organisations that will interact with, or depend on, the API.
When representatives for the potential actors are identified, start co-designing with these representatives. First and foremost, consider the requirements for the API. Application developers often couch their requirements in terms of how the API should work, rather than what the API needs to do. Don’t get bogged down in the variety of proposed solutions from each developer: focus on extracting their true requirements by performing functional analysis (e.g. use cases) and data flow analysis. Then identify resources and work out the granularity needed (see Granularity).
It is especially important that security and information privacy impacts are identified up front and addressed early on in the design process. Assess the information being passed and the types of access different customers and/or consuming applications should have to the API. This will help drive development of security policies alongside the design of the API.
One common pitfall in API design is to map all existing data tables onto resources and develop the associated CRUD capabilities into an API. Usually this results in a poor API design and tightly couples the API design to the underlying data structure. Another common pitfall is to design APIs as an extension to, or way into, monolithic legacy systems. This should be avoided as it tightly couples the API to the legacy system. Both of these pitfalls will create issues for both API providers and API consumers in the long term.
At this point in the design process, agility is probably more important than completeness. Share early design thoughts and interface specifications with the developer community and quickly make changes in response to their feedback. Work through some sequence diagrams with them to help pin down API interactions and inform API design thinking.
The correct API design will likely not please every developer, so don’t try to be all things to all developers. A rule of thumb is that you are probably on the right track if most developers are a little unhappy, but all are able to achieve their aims with the proposed design.
It is important not to try to bypass evolution steps and try to build for all potential use cases right from the offset. For a more measured progression towards API delivery, start simple and focus on a single channel or interaction initially. By building onto these simple building blocks, API evolution over time naturally progress towards omnichannel applications.